{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表生成式即List Comprehensions，是Python内置的非常简单却强大的可以用来创建list的生成式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 用list(range())生成列表:\n",
    "list(range(1, 11))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 生成[1x1, 2x2, 3x3, ..., 10x10]\n",
    "# 方法一:循环\n",
    "L = []\n",
    "for i in range(1,11):\n",
    "    L.append(i*i)\n",
    "L"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 方法二:列表生成式\n",
    "[i*i for i in range(1,11)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# for循环后加if判断,筛选出仅偶数的平方\n",
    "[i*i for i in range(1,11) if i%2 == 0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用两层循环, 生成全排列:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "[m + n for m in 'ABC' for n in 'XYZ']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " 运用列表生成式，可以写出非常简洁的代码。\n",
    " \n",
    " 例如，列出当前目录下的所有文件和目录名，可以通过一行代码实现："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['.ipynb_checkpoints', '切片.ipynb', '列表生成式.ipynb', '迭代.ipynb']"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os # 导入os模块，模块的概念后面讲到\n",
    "[d for d in os.listdir('.')] # os.listdir可以列出文件和目录"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "列表生成式也可以使用两个变量来生成list："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['x=A', 'y=B', 'z=C']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "d = {'x': 'A', 'y': 'B', 'z': 'C' }\n",
    "[k + '=' + v for k, v in d.items()]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['hello', 'world', 'ibm', 'apple']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 最后把一个list中所有的字符串变成小写：\n",
    "L = ['Hello', 'World', 'IBM', 'Apple']\n",
    "[s.lower() for s in L]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在一个列表生成式中，for前面的if ... else是表达式，而for后面的if是过滤条件，不能带else"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-9-0846473fb08f>, line 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-9-0846473fb08f>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m    [x if x % 2 == 0 for x in range(1, 11)]\u001b[0m\n\u001b[1;37m                       ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "[x if x % 2 == 0 for x in range(1, 11)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "[x if x % 2 == 0 else -x for x in range(1, 11)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "[x for x in range(1, 11) if x % 2 == 0 else 0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 练习\n",
    "如果list中既包含字符串，又包含整数，由于非字符串类型没有lower()方法，所以列表生成式会报错："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "L = ['Hello', 'World', 18, 'Apple', None]\n",
    "[s.lower() for s in L]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用内建的isinstance函数可以判断一个变量是不是字符串："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 'abc'\n",
    "y = 123\n",
    "isinstance(x, str)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "请修改列表生成式，通过添加if语句保证列表生成式能正确地执行："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['hello', 'world', 'apple']\n",
      "测试通过!\n"
     ]
    }
   ],
   "source": [
    "L = ['Hello', 'World', 18, 'Apple', None]\n",
    "L2 = [s.lower()for s in L if isinstance(s,str)]\n",
    "# 测试\n",
    "print(L2)\n",
    "if L2 == ['hello', 'world', 'apple']:\n",
    "    print('测试通过!')\n",
    "else:\n",
    "    print('测试失败!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
